package net.flyinggroup.scs.gitter.service.impl.utils;

import net.flyinggroup.scs.gitter.controller.vm.MessageVM;
import net.flyinggroup.scs.gitter.domain.Issue;
import net.flyinggroup.scs.gitter.domain.Mention;
import net.flyinggroup.scs.gitter.domain.Message;
import net.flyinggroup.scs.gitter.domain.User;
import net.flyinggroup.scs.gitter.service.gitter.dto.MessageResponse;
import net.flyinggroup.scs.gitter.service.gitter.dto.Url;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

public class MessageMapper {
    private MessageMapper() {
    }

    public static List<MessageVM> toViewModelUnits(Iterable<MessageResponse> messages) {
        if (messages == null) {
            return null;
        }
        List<MessageVM> vms = new ArrayList<>();
        messages.forEach(msg -> vms.add(toViewModelUnit(msg)));
        return vms;
    }

    public static MessageVM toViewModelUnit(MessageResponse msg) {
        return msg == null ? null : new MessageVM(msg.getId(),
                msg.getText(),
                msg.getHtml(),
                msg.getFromUser().getUsername(),
                msg.getFromUser().getAvatarUrl(),
                msg.getSent());
    }

    public static List<Message> toDomainUnits(Iterable<MessageResponse> messages) {
        if (messages == null) return null;
        List<Message> persistable = new ArrayList<>();
        messages.forEach(msg -> persistable.add(toDomainUnit(msg)));
        return persistable;
    }

    public static Message toDomainUnit(MessageResponse msg) {
        if (msg == null) return null;
        return Message.builder()
                .id(msg.getId())
                .html(msg.getHtml())
                .text(msg.getText())
                .sent(msg.getSent())
                .readBy(msg.getReadBy())
                .unread(Objects.nonNull(msg.getUnRead()) ? msg.getUnRead() : false)
                .user(User.of(msg.getFromUser().getId(), msg.getFromUser().getUsername(), msg.getFromUser().getDisplayName()))
                .urls(msg.getUrls().stream()
                        .map(Url::getUrl)
                        .toArray(String[]::new))
                .mentions(msg.getMentions().stream()
                        .filter(m -> Objects.nonNull(m.getUserId()))
                        .map(m -> Mention.of(m.getUserId(), m.getScreenName()))
                        .collect(Collectors.toSet()))
                .issues(msg.getIssues().stream()
                        .map(i -> Issue.of(Long.valueOf(i.getNumber())))
                        .collect(Collectors.toSet()))
                .build();
    }
}
